# -*- coding: utf-8 -*-
"""
QAD API 接口配置模型
用于管理 API 接口端点配置
"""

from odoo import models, fields, api, _
from odoo.exceptions import ValidationError
import logging
from datetime import datetime

_logger = logging.getLogger(__name__)


class QADAPIEndpoint(models.Model):
    """QAD API 接口端点配置"""
    _name = 'qad.api.endpoint'
    _description = 'QAD API Endpoint Configuration'
    _rec_name = 'endpoint_name'
    _order = 'server_config_id, endpoint_name'

    # 基本信息
    endpoint_name = fields.Char(
        string='接口名称',
        required=True,
        index=True,
        help='API 接口的名称，用于标识此接口'
    )
    active = fields.Boolean(
        string='启用',
        default=True,
        help='是否启用此接口'
    )
    
    # 关联服务器配置
    server_config_id = fields.Many2one(
        'qad.server.config',
        string='服务器配置',
        required=True,
        ondelete='restrict',
        help='此接口使用的服务器配置'
    )
    server_code = fields.Char(
        string='服务器代码',
        related='server_config_id.server_code',
        store=True,
        readonly=True,
        help='服务器配置的代码'
    )
    
    # 接口配置
    additional_path = fields.Char(
        string='附加路径名',
        help='接口的附加路径，将追加到基础路径后面。例如：/api/v1/data'
    )
    application_name = fields.Char(
        string='应用程序名',
        required=True,
        help='要执行的应用程序或脚本名称'
    )
    
    # 完整 API 路径（只读，自动计算）
    api_path = fields.Char(
        string='API 路径',
        compute='_compute_api_path',
        store=True,
        help='完整的 API 访问路径'
    )
    
    # 执行参数
    script_parameters = fields.Char(
        string='脚本参数',
        help='执行脚本时传递的额外参数'
    )
    output_format = fields.Selection([
        ('json', 'JSON'),
        ('xml', 'XML'),
        ('text', '纯文本'),
    ], string='输出格式', default='json',
       help='API 返回数据的格式')
    
    # 文件处理配置
    json_filename_pattern = fields.Char(
        string='JSON 文件名模式',
        default='*.json',
        help='要读取的 JSON 文件名模式，支持通配符。例如：output_*.json'
    )
    max_file_age_hours = fields.Integer(
        string='最大文件时效（小时）',
        default=24,
        help='只读取指定时间内的文件，超时的文件将被忽略'
    )
    
    # 认证配置
    require_api_key = fields.Boolean(
        string='需要 API Key',
        default=True,
        help='是否需要 API Key 认证'
    )
    allowed_user_ids = fields.Many2many(
        'res.users',
        'qad_endpoint_user_rel',
        'endpoint_id',
        'user_id',
        string='允许的用户',
        help='允许访问此接口的用户列表（留空表示所有用户）'
    )
    
    # 访问限制
    rate_limit_per_minute = fields.Integer(
        string='每分钟请求限制',
        default=60,
        help='每个用户每分钟允许的最大请求次数，0 表示不限制'
    )
    
    # 统计信息
    total_calls = fields.Integer(
        string='总调用次数',
        default=0,
        readonly=True,
        help='此接口被调用的总次数'
    )
    successful_calls = fields.Integer(
        string='成功调用次数',
        default=0,
        readonly=True,
        help='成功返回数据的调用次数'
    )
    failed_calls = fields.Integer(
        string='失败调用次数',
        default=0,
        readonly=True,
        help='失败的调用次数'
    )
    last_call_time = fields.Datetime(
        string='最后调用时间',
        readonly=True,
        help='最后一次被调用的时间'
    )
    last_call_status = fields.Selection([
        ('success', '成功'),
        ('failed', '失败'),
    ], string='最后调用状态', readonly=True)
    last_error_message = fields.Text(
        string='最后错误信息',
        readonly=True,
        help='最后一次调用失败的错误信息'
    )
    avg_response_time = fields.Float(
        string='平均响应时间（秒）',
        readonly=True,
        help='接口的平均响应时间'
    )
    
    # 备注
    description = fields.Text(
        string='接口描述',
        help='关于此接口的详细描述'
    )
    notes = fields.Text(
        string='备注',
        help='额外的备注信息'
    )
    
    # SQL 约束
    _sql_constraints = [
        ('endpoint_name_server_unique', 
         'UNIQUE(endpoint_name, server_config_id)',
         '同一服务器配置下的接口名称必须唯一！'),
    ]
    
    @api.depends('endpoint_name', 'server_config_id.server_code')
    def _compute_api_path(self):
        """计算完整的 API 路径（不含 additional_path）"""
        for record in self:
            base_path = '/api/qad'
            server_code = record.server_config_id.server_code or 'default'
            endpoint = record.endpoint_name or 'endpoint'
            
            # 构建路径（不包含 additional_path）
            # additional_path 只用于文件路径，不在 API URL 中
            path_parts = [base_path, server_code, endpoint]
            
            record.api_path = '/'.join(path_parts)
    
    @api.constrains('rate_limit_per_minute')
    def _check_rate_limit(self):
        """检查请求限制是否有效"""
        for record in self:
            if record.rate_limit_per_minute < 0:
                raise ValidationError(_('每分钟请求限制不能为负数！'))
    
    @api.constrains('max_file_age_hours')
    def _check_max_file_age(self):
        """检查文件时效是否有效"""
        for record in self:
            if record.max_file_age_hours < 0:
                raise ValidationError(_('最大文件时效不能为负数！'))
    
    def action_test_endpoint(self):
        """测试接口（模拟调用）"""
        self.ensure_one()
        
        try:
            # 检查服务器配置是否有效
            if not self.server_config_id.active:
                raise ValidationError(_('服务器配置未启用！'))
            
            message = _(
                '✅ 接口配置有效！\n\n'
                '📍 API 路径：%s\n'
                '🖥️  服务器：%s\n'
                '📦 应用程序：%s\n'
                '🔑 需要认证：%s\n'
                '📊 总调用次数：%s'
            ) % (
                self.api_path,
                self.server_config_id.name,
                self.application_name,
                '是' if self.require_api_key else '否',
                self.total_calls
            )
            
            return {
                'type': 'ir.actions.client',
                'tag': 'display_notification',
                'params': {
                    'title': _('接口测试'),
                    'message': message,
                    'type': 'success',
                    'sticky': False,
                }
            }
            
        except Exception as e:
            return {
                'type': 'ir.actions.client',
                'tag': 'display_notification',
                'params': {
                    'title': _('接口测试失败'),
                    'message': str(e),
                    'type': 'danger',
                    'sticky': True,
                }
            }
    
    def increment_call_stats(self, success=True, response_time=0, error_message=None):
        """更新调用统计信息"""
        self.ensure_one()
        
        vals = {
            'total_calls': self.total_calls + 1,
            'last_call_time': fields.Datetime.now(),
            'last_call_status': 'success' if success else 'failed',
        }
        
        if success:
            vals['successful_calls'] = self.successful_calls + 1
            vals['last_error_message'] = False
            
            # 计算平均响应时间
            if self.avg_response_time > 0:
                vals['avg_response_time'] = (
                    self.avg_response_time * (self.total_calls - 1) + response_time
                ) / self.total_calls
            else:
                vals['avg_response_time'] = response_time
        else:
            vals['failed_calls'] = self.failed_calls + 1
            vals['last_error_message'] = error_message
        
        self.write(vals)
    
    def action_reset_stats(self):
        """重置统计信息"""
        for record in self:
            record.write({
                'total_calls': 0,
                'successful_calls': 0,
                'failed_calls': 0,
                'last_call_time': False,
                'last_call_status': False,
                'last_error_message': False,
                'avg_response_time': 0,
            })
        
        return {
            'type': 'ir.actions.client',
            'tag': 'display_notification',
            'params': {
                'title': _('统计信息已重置'),
                'message': _('接口的统计信息已重置为初始值'),
                'type': 'success',
                'sticky': False,
            }
        }
    
    def action_refresh_api_path(self):
        """刷新 API 路径（强制重新计算）"""
        for record in self:
            record._compute_api_path()
        
        return {
            'type': 'ir.actions.client',
            'tag': 'display_notification',
            'params': {
                'title': _('API 路径已刷新'),
                'message': _('%d 个接口的 API 路径已重新计算') % len(self),
                'type': 'success',
                'sticky': False,
            }
        }

    @api.model
    def _generate_unique_endpoint_name(self, base_name):
        """生成唯一的接口名称"""
        if not base_name:
            base_name = "ENDPOINT"
        
        # 移除末尾的数字和 _COPY_ 部分（如果有的话）
        base_name = base_name.rstrip('0123456789')
        if base_name.endswith('_COPY'):
            base_name = base_name[:-5]  # 移除 _COPY
        
        counter = 1
        new_name = f"{base_name}_COPY_{counter}"
        
        # 确保名称唯一
        while self.search([('endpoint_name', '=', new_name)], limit=1):
            counter += 1
            new_name = f"{base_name}_COPY_{counter}"
        
        return new_name

    def copy(self, default=None):
        """复制记录时生成临时的唯一值"""
        if default is None:
            default = {}
        
        # 生成临时的接口名称
        original_name = self.endpoint_name or "ENDPOINT"
        temp_name = self._generate_unique_endpoint_name(original_name)
        
        default.update({
            'endpoint_name': temp_name,
            'description': f"{self.description} (副本)" if self.description else "接口配置副本",
            'active': False,  # 默认禁用，避免意外使用
        })
        
        return super(QADAPIEndpoint, self).copy(default)

